home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / tnzs.c < prev    next >
C/C++ Source or Header  |  2000-01-03  |  9KB  |  339 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8. #include "driver.h"
  9. #include "vidhrdw/generic.h"
  10. #include "ctype.h"
  11.  
  12.  
  13.  
  14. extern unsigned char *tnzs_objram;
  15. extern unsigned char *tnzs_vdcram;
  16. extern unsigned char *tnzs_scrollram;
  17.  
  18.  
  19. static struct osd_bitmap *tnzs_column[16];
  20. static int tnzs_dirty_map[32][16];
  21. static int tnzs_screenflip, old_tnzs_screenflip;
  22.  
  23. /***************************************************************************
  24.  
  25.   The New Zealand Story doesn't have a color PROM. It uses 1024 bytes of RAM
  26.   to dynamically create the palette. Each couple of bytes defines one
  27.   color (15 bits per pixel; the top bit of the second byte is unused).
  28.   Since the graphics use 4 bitplanes, hence 16 colors, this makes for 32
  29.   different color codes.
  30.  
  31. ***************************************************************************/
  32.  
  33.  
  34. /***************************************************************************
  35.  
  36.   Convert the color PROMs into a more useable format.
  37.  
  38.   Arkanoid has a two 512x8 palette PROMs. The two bytes joined together
  39.   form 512 xRRRRRGGGGGBBBBB color values.
  40.  
  41. ***************************************************************************/
  42. void arkanoi2_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  43. {
  44.     int i,col;
  45.  
  46.     for (i = 0;i < Machine->drv->total_colors;i++)
  47.     {
  48.         col = (color_prom[i]<<8)+color_prom[i+512];
  49.         *(palette++) =  (col & 0x7c00)>>7;    /* Red */
  50.         *(palette++) =  (col & 0x03e0)>>2;    /* Green */
  51.         *(palette++) =  (col & 0x001f)<<3;    /* Blue */
  52.     }
  53. }
  54.  
  55.  
  56.  
  57. /***************************************************************************
  58.  
  59.   Start the video hardware emulation.
  60.  
  61. ***************************************************************************/
  62. int tnzs_vh_start(void)
  63. {
  64.     int column,x,y;
  65.     for (column=0;column<16;column++)
  66.     {
  67.         if ((tnzs_column[column] = osd_create_bitmap(32,256)) == 0)
  68.         {
  69.             /* Free all the columns */
  70.             for (column--;column;column--)
  71.                 osd_free_bitmap(tnzs_column[column]);
  72.             return 1;
  73.         }
  74.     }
  75.  
  76.     for (x=0;x<32;x++)
  77.     {
  78.         for (y=0;y<16;y++)
  79.         {
  80.             tnzs_dirty_map[x][y] = -1;
  81.         }
  82.     }
  83.  
  84.     return 0;
  85. }
  86.  
  87.  
  88.  
  89. /***************************************************************************
  90.  
  91.   Stop the video hardware emulation.
  92.  
  93. ***************************************************************************/
  94. void tnzs_vh_stop(void)
  95. {
  96.     int column;
  97.  
  98.     /* Free all the columns */
  99.     for (column=0;column<16;column++)
  100.         osd_free_bitmap(tnzs_column[column]);
  101. }
  102.  
  103.  
  104.  
  105. /***************************************************************************
  106.  
  107.   Draw the game screen in the given osd_bitmap.
  108.   Do NOT call osd_update_display() from this function, it will be called by
  109.   the main emulation engine.
  110.  
  111. ***************************************************************************/
  112.  
  113. void tnzs_vh_draw_background(struct osd_bitmap *bitmap,unsigned char *m)
  114. {
  115.     int i,x,y,column,tot;
  116.     int scrollx, scrolly;
  117.     unsigned int upperbits;
  118.  
  119.     /* The screen is split into 16 columns.
  120.        So first, update the tiles. */
  121.     for (i=0,column=0;column<16;column++)
  122.     {
  123.         for (y=0;y<16;y++)
  124.         {
  125.             for (x=0;x<2;x++,i++)
  126.             {
  127.                 int tile;
  128.  
  129.                 /* Construct unique identifier for this tile/color */
  130.                 tile = (m[i + 0x1200] << 16) | (m[i + 0x1000] << 8) | m[i];
  131.  
  132.                 if (tnzs_dirty_map[column*2+x][y] != tile)
  133.                 {
  134.                     int code,color,flipx,flipy,sx,sy;
  135.  
  136.  
  137.                     tnzs_dirty_map[column*2+x][y] = tile;
  138.  
  139.                     code = m[i] + ((m[i + 0x1000] & 0x1f) << 8);
  140.                     color = (m[i + 0x1200] & 0xf8) >> 3; /* colours at d600-d7ff */
  141.                     sx = x*16;
  142.                     sy = y*16;
  143.                     flipx = m[i + 0x1000] & 0x80;
  144.                     flipy = m[i + 0x1000] & 0x40;
  145.                     if (tnzs_screenflip)
  146.                     {
  147.                         sy = 240 - sy;
  148.                         flipx = !flipx;
  149.                         flipy = !flipy;
  150.                     }
  151.  
  152.                     drawgfx(tnzs_column[column],Machine->gfx[0],
  153.                             code,
  154.                             color,
  155.                             flipx,flipy,
  156.                             sx,sy,
  157.                             0,TRANSPARENCY_NONE,0);
  158.                 }
  159.             }
  160.         }
  161.     }
  162.  
  163.     /* If the byte at f301 has bit 0 clear, then don't draw the
  164.        background tiles -WRONG- */
  165.  
  166.     /* The byte at f200 is the y-scroll value for the first column.
  167.        The byte at f204 is the LSB of x-scroll value for the first column.
  168.  
  169.        The other columns follow at 16-byte intervals.
  170.  
  171.        The 9th bit of each x-scroll value is combined into 2 bytes
  172.        at f302-f303 */
  173.  
  174.     /* f301 seems to control how many columns are drawn but it's not clear how. */
  175.     /* Arkanoid 2 also uses f381, which TNZS always leaves at 00. */
  176.     /* Maybe it's a background / foreground thing? In Arkanoid 2, f381 contains */
  177.     /* the value we expect for the background stars (2E vs. 2A), while f301 the */
  178.     /* one we expect at the beginning of a level (2C vs. 2A). */
  179.     x = tnzs_scrollram[0x101] & 0xf;
  180.     if (x == 1) x = 16;
  181.     y = tnzs_scrollram[0x181] & 0xf;
  182.     if (y == 1) y = 16;
  183.     /* let's just pick the larger value... */
  184.     tot = x;
  185.     if (y > tot) tot = y;
  186.  
  187.     upperbits = tnzs_scrollram[0x102] + tnzs_scrollram[0x103] * 256;
  188.     /* again, it's not clear why there are two areas, but Arkanoid 2 uses these */
  189.     /* for the end of game animation */
  190.     upperbits |= tnzs_scrollram[0x182] + tnzs_scrollram[0x183] * 256;
  191.  
  192.     for (column = 0;column < tot;column++)
  193.     {
  194.         scrollx = tnzs_scrollram[column*16+4] - ((upperbits & 0x01) * 256);
  195.         if (tnzs_screenflip)
  196.             scrolly = tnzs_scrollram[column*16] + 1 - 256;
  197.         else
  198.             scrolly = -tnzs_scrollram[column*16] + 1;
  199.  
  200.         copybitmap(bitmap,tnzs_column[column^8],0,0,scrollx,scrolly,
  201.                    &Machine->drv->visible_area,TRANSPARENCY_COLOR,0);
  202.         copybitmap(bitmap,tnzs_column[column^8],0,0,scrollx,scrolly+(16*16),
  203.                    &Machine->drv->visible_area,TRANSPARENCY_COLOR,0);
  204.  
  205.         upperbits >>= 1;
  206.     }
  207. }
  208.  
  209. void tnzs_vh_draw_foreground(struct osd_bitmap *bitmap,
  210.                              unsigned char *char_pointer,
  211.                              unsigned char *x_pointer,
  212.                              unsigned char *y_pointer,
  213.                              unsigned char *ctrl_pointer,
  214.                              unsigned char *color_pointer)
  215. {
  216.     int i;
  217.  
  218.  
  219.     /* Draw all 512 sprites */
  220.     for (i=0x1ff;i >= 0;i--)
  221.     {
  222.         int code,color,sx,sy,flipx,flipy;
  223.  
  224.         code = char_pointer[i] + ((ctrl_pointer[i] & 0x1f) << 8);
  225.         color = (color_pointer[i] & 0xf8) >> 3;
  226.         sx = x_pointer[i] - ((color_pointer[i] & 1) << 8);
  227.         sy = 240 - y_pointer[i];
  228.         flipx = ctrl_pointer[i] & 0x80;
  229.         flipy = ctrl_pointer[i] & 0x40;
  230.         if (tnzs_screenflip)
  231.         {
  232.             sy = 240 - sy;
  233.             flipx = !flipx;
  234.             flipy = !flipy;
  235.             /* hack to hide Chuka Taisens grey line, top left corner */
  236.             if ((sy == 0) && (code == 0)) sy += 240;
  237.         }
  238.  
  239.         drawgfx(bitmap,Machine->gfx[0],
  240.                 code,
  241.                 color,
  242.                 flipx,flipy,
  243.                 sx,sy+2,
  244.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  245.     }
  246. }
  247.  
  248. void arkanoi2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  249. {
  250.     int x,y;
  251.  
  252.     /* If the byte at f300 has bit 6 set, flip the screen
  253.        (I'm not 100% sure about this) */
  254.     tnzs_screenflip = (tnzs_scrollram[0x100] & 0x40) >> 6;
  255.     if (old_tnzs_screenflip != tnzs_screenflip)
  256.     {
  257.         for (x=0;x<32;x++)
  258.         {
  259.             for (y=0;y<16;y++)
  260.             {
  261.                 tnzs_dirty_map[x][y] = -1;
  262.             }
  263.         }
  264.     }
  265.     old_tnzs_screenflip = tnzs_screenflip;
  266.  
  267.  
  268.     /* Blank the background */
  269.     fillbitmap(bitmap, Machine->pens[0], &Machine->drv->visible_area);
  270.  
  271.     /* Redraw the background tiles (c400-c5ff) */
  272.     tnzs_vh_draw_background(bitmap, tnzs_objram + 0x400);
  273.  
  274.     /* Draw the sprites on top */
  275.     tnzs_vh_draw_foreground(bitmap,
  276.                             tnzs_objram + 0x0000, /*  chars : c000 */
  277.                             tnzs_objram + 0x0200, /*      x : c200 */
  278.                             tnzs_vdcram + 0x0000, /*      y : f000 */
  279.                             tnzs_objram + 0x1000, /*   ctrl : d000 */
  280.                             tnzs_objram + 0x1200); /* color : d200 */
  281. }
  282.  
  283. void tnzs_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  284. {
  285.     int color,code,i,offs,x,y;
  286.     int colmask[32];
  287.  
  288.     /* Remap dynamic palette */
  289.     palette_init_used_colors();
  290.  
  291.     for (color = 0;color < 32;color++) colmask[color] = 0;
  292.  
  293.     /* See what colours the tiles need */
  294.     for (offs=32*16 - 1;offs >= 0;offs--)
  295.     {
  296.         code = tnzs_objram[offs + 0x400]
  297.              + 0x100 * (tnzs_objram[offs + 0x1400] & 0x1f);
  298.         color = tnzs_objram[offs + 0x1600] >> 3;
  299.  
  300.         colmask[color] |= Machine->gfx[0]->pen_usage[code];
  301.     }
  302.  
  303.     /* See what colours the sprites need */
  304.     for (offs=0x1ff;offs >= 0;offs--)
  305.     {
  306.         code = tnzs_objram[offs]
  307.              + 0x100 * (tnzs_objram[offs + 0x1000] & 0x1f);
  308.         color = tnzs_objram[offs + 0x1200] >> 3;
  309.  
  310.         colmask[color] |= Machine->gfx[0]->pen_usage[code];
  311.     }
  312.  
  313.     /* Construct colour usage table */
  314.     for (color=0;color<32;color++)
  315.     {
  316.         if (colmask[color] & (1 << 0))
  317.             palette_used_colors[16 * color] = PALETTE_COLOR_TRANSPARENT;
  318.         for (i=1;i<16;i++)
  319.         {
  320.             if (colmask[color] & (1 << i))
  321.                 palette_used_colors[16 * color + i] = PALETTE_COLOR_USED;
  322.         }
  323.     }
  324.  
  325.     if (palette_recalc())
  326.     {
  327.         for (x=0;x<32;x++)
  328.         {
  329.             for (y=0;y<16;y++)
  330.             {
  331.                 tnzs_dirty_map[x][y] = -1;
  332.             }
  333.         }
  334.     }
  335.  
  336.  
  337.     arkanoi2_vh_screenrefresh(bitmap,full_refresh);
  338. }
  339.